path = "/gpfs/hpchome/a72094/rocket/projects/chromatin_to_splicing/"
Warning message:
no function found corresponding to methods exports from ‘XVector’ for: ‘concatenateObjects’
library("dplyr")
Attaching package: ‘dplyr’
The following objects are masked from ‘package:GenomicRanges’:
intersect, setdiff, union
The following object is masked from ‘package:GenomeInfoDb’:
intersect
The following objects are masked from ‘package:IRanges’:
collapse, desc, intersect, setdiff, slice, union
The following objects are masked from ‘package:S4Vectors’:
first, intersect, rename, setdiff, setequal, union
The following objects are masked from ‘package:BiocGenerics’:
combine, intersect, setdiff, union
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
library("readr")
library("devtools")
library("rtracklayer")
library("wiggleplotr")
library("GenomicRanges")
library('Rsamtools')
Loading required package: Biostrings
Loading required package: XVector
Attaching package: ‘Biostrings’
The following object is masked from ‘package:base’:
strsplit
library('tidyr')
Attaching package: ‘tidyr’
The following object is masked from ‘package:S4Vectors’:
expand
load_all("/gpfs/rocket/home/a72094/projects/chromatin_to_splicing/seqUtils/")
Loading seqUtils
Splaissimise andmed
#geenid, millel leidub splaiss QTL
splicing = read.table(paste0(path, "tabix/txrevise.significant.contained.sorted.txt.gz"))
#r2 seotud splass ja ca lookuste paarid
ca_splicing = read.table(paste0(path, "results/rsquared08/cqn_contained_rsq.txt"))
Kromatiini avatuse andmed
Aluseks peavad olema kromatiini avatuse kühmud, millel leidub: 1. statistiliselt oluline caQTL 25872 2. caQTL on seotud splaiss QTL’ga
Alustuseks leian kõik kühmud, mis vastavad kriteeriumitele
ca_interesting_peaks = ca[which(ca$V8 %in% ca_splicing$V1),]
Error: object 'ca' not found
Geenid, mille splaissimine on R2 seotud kromatiini avatusega
interesting_genes = splicing[which(splicing$V10 %in% ca_splicing$V4),c("V1", "V2", "V3","V4","V10","V12","V19","V21")]
colnames(interesting_genes) = c("gene_id", "gene_chr","gene_start","gene_end","gene_snpid", "gene_snp_pos","gene_slope","gene_pvalue")
interesting_genes
Seon kromatiini kühmud ja geenid
interesting = dplyr::left_join(interesting_genes, ca_splicing, by = c("gene_snpid"="V4"))[1:9] %>% left_join(interesting_peaks, ., by=c('peak_snpid'='V1'))
Column `gene_snpid`/`V4` joining factors with different levels, coercing to character vectorColumn `peak_snpid`/`V1` joining factors with different levels, coercing to character vector
interesting = dplyr::select(interesting, -one_of('ctcf_chr','gene_chr', 'peak_snp_chr'))
Unknown columns: `ctcf_chr`
interesting$gene_id = substr(interesting$gene_id, 1, nchar("ENSG00000171735.contained")-10)
interesting
write.table(interesting, file = paste0(path, 'interesting.txt'), col.names = T, quote = F, row.names = F, append = F)
interesting = read.table(paste0(path, 'interesting.txt'), header = TRUE)
filtered = interesting[which(abs(interesting$peak_slope)>0.4 & abs(interesting$gene_slope)>0.4 & interesting$ca_pvalue<1e-4 & interesting$gene_pvalue<1e-4),]
filtered
ATAC
#proovid
ATAC_sample_metadata = read.table(paste0(path,'QC_measures/run_sample_accession_PhaseIII.txt'))
colnames(ATAC_sample_metadata) = c("sample_id", "genotype_id")
ATAC_sample_metadata["condition_name"] = rep("naive", dim(ATAC_sample_metadata)[1])
#genotüübid
vcf_file = readRDS(paste0(path, 'genotypes/Kumasaka_100_samples.merged.rds'))
ATAC_meta_df = read.table(paste0(path, 'ATAC_meta_df'), header = TRUE)
ATAC_peak_metadata = read.table(paste0(path,'ATAC_peak_metadata'), header = TRUE)
regions_df = unique(filtered[,c('peak_id', 'peak_chr','peak_start', 'peak_end','peak_snpid','gene_id', 'peak_chr','gene_start', 'gene_end','gene_snpid','gene_snp_pos')])
colnames(regions_df) = c('peak_id', 'peak_chr', 'peak_start', 'peak_end', 'peak_rs_id', 'gene_id', 'gene_chr', 'gene_start', 'gene_end', 'gene_rs_id', 'gene_pos')
regions_df
#rm(vcf_file,ATAC_counts)
RNA
RNA_sample_metadata = read.table("/gpfs/hpchome/a72094/hpc/datasets/controlled_access/SampleArcheology/studies/cleaned/GEUVADIS.tsv", header = TRUE)[,c("sample_id","genotype_id","condition")]
colnames(RNA_sample_metadata)[3] = "condition_name"
if (FALSE){
# RNA seq lugemite arv used for calculating library size
RNA_counts = read.table("/gpfs/hpchome/a72094/hpc/projects/RNAseq_pipeline/results/expression_matrices/featureCounts/GEUVADIS.tsv.gz", header = TRUE)
RNA_meta_df = wiggleplotrConstructMetadata(RNA_counts, RNA_sample_metadata, "/gpfs/hpc/home/a72094/projects/RNAseq_pipeline/processed/GEUVADIS/bigwig", bigWig_suffix = ".str1.bw", condition_name_levels = c("naive"))
rm(RNA_counts)
saveRDS(RNA_meta_df, paste0(path, 'RNA_meta_df'))
}
RNA_meta_df = readRDS(paste0(path, 'RNA_meta_df'))
RNA_meta_df
regions_df = unique(filtered[,c('gene_id', 'peak_chr','gene_start', 'gene_end','gene_snpid','gene_snp_pos')])
colnames(regions_df) = c('gene_id', 'chr', 'start', 'end', 'rs_id', 'pos')
regions_df
geenide annotatsioonid ja transkriptide annotatsioonid
gtf_df <- as.data.frame(rtracklayer::import(paste0(path, 'genotypes/Homo_sapiens.GRCh38.96.chr.gtf.gz')))
filtered_annotations = gtf_df[gtf_df$gene_id %in% regions_df$gene_id,]
filtered_annotations
rm(gtf_df)
saveRDS(filtered_annotations, paste0(path, 'filtered_annotations'))
filtered_annotations = readRDS(paste0(path, 'filtered_annotations'))
filtered_annotations
Koik geeni eksonid GRanges objektidena
find_peak_annotations = function(region_coords, chr, RNA_peak_metadata){
RNA_peak_annot = wiggleplotrExtractPeaks(region_coords, chrom = chr, RNA_peak_metadata)
RNA_peak_annot$peak_annot$transcript_id='RNA'
RNA_peak_annot$peak_annot$gene_id = 'RNA'
RNA_peak_annot$peak_annot$gene_name = 'RNA-seq'
names(RNA_peak_annot$peak_list) = 'RNA'
return(RNA_peak_annot)
}
Leian vcf failist loigu, mis vastab uuritavale geenile
find_genotype = function(gene_id, region_coords){
library(GenomicRanges)
gene_range = GRanges(seqnames =filtered_annotations[which(filtered_annotations$type=='gene' & filtered_annotations$gene_id ==gene_id),'seqnames'], strand = c("*"), ranges = IRanges(start = region_coords[1], end = region_coords[2], names = gene_id))
vcf_file = paste0(path, 'genotypes/GEUVADIS_GRCh38_filtered.vcf.gz')
genotype = scanTabixDataFrame(vcf_file, gene_range, col_names = FALSE)[[1]]
#saveRDS(genotype, paste0(path, 'genotype'))
#zgrep -m 1 "#CHROM" GEUVADIS_GRCh38_filtered.vcf.gz > vcf_genotype_id
#vim vcf_genotype_id delete #
v = scan(paste0(path, '/genotypes/vcf_genotype_id'), character(), quote = "")
#unlink(paste0(path, '/genotypes/vcf_genotype_id'))
colnames(genotype) = v
genotype[genotype=="0|0"]<-0
genotype[genotype=="1|0"]<-1
genotype[genotype=="0|1"]<-1
genotype[genotype=="1|1"]<-2
return(genotype)
}
find_track_data = function(genotype, chr, RNA_meta_df){
# add colour group
colour_group = genotype[which(genotype$CHROM==chr & genotype$POS==pos), ] %>% select(10:454) %>% gather(., key= colnames(.), value=.[1,])
colnames(colour_group) = c('genotype_id', 'colour_group')
RNA_track_data = dplyr::left_join(RNA_meta_df, colour_group, by='genotype_id') %>% dplyr::mutate(track_id = "RNA-seq")
RNA_track_data[, 'colour_group'] = as.factor(RNA_track_data[, 'colour_group'])
return(RNA_track_data)
}
ATAC joonised
joint_plotlist = list()
for (i in 1:dim(regions_df)[1]){
ATAC_rs_id = regions_df[i, 'peak_rs_id']
ATAC_region_coords=c(regions_df[i,'peak_start']-1000, regions_df[i,'peak_end']+1000)
chr = regions_df[i,'peak_chr']
ATAC_peak_annot = wiggleplotrExtractPeaks(region_coords, chrom = chr, ATAC_peak_metadata)
# add colour group
ATAC_colour_group = data.frame(genotype_id = names(vcf_file$genotypes[ATAC_rs_id,]), colour_group=vcf_file$genotypes[rs_id,])
ATAC_track_data = dplyr::left_join(ATAC_meta_df, ATAC_colour_group, by='genotype_id') %>% dplyr::mutate(track_id = "ATAC-seq")
ATAC_track_data[, 'colour_group'] = as.factor(ATAC_track_data[, 'colour_group'])
ATAC_coverage = plotCoverage(exons = ATAC_peak_annot$peak_list, cdss = ATAC_peak_annot$peak_list, track_data = ATAC_track_data, rescale_introns = FALSE,
transcript_annotations = ATAC_peak_annot$peak_annot, fill_palette = getGenotypePalette(),
connect_exons = FALSE, transcript_label = FALSE, plot_fraction = 0.1, heights = c(0.7,0.3),
region_coords = ATAC_region_coords, return_subplots_list = TRUE, coverage_type = "line")
joint_plot = cowplot::plot_grid(ATAC_coverage$coverage_plot,
ATAC_coverage$tx_structure,
align = "v", ncol = 1, rel_heights = c(3,2))
joint_plotlist[[i]] = joint_plot
print(joint_plot)
ggsave(paste0('/gpfs/hpchome/evelin95/plots/ca_splicing/',regions_df[i,'peak_id'],'.pdf'))
}
RNA joonised
library(ggplot2)
RNA_coverage_plotlist = list()
for (i in 1:dim(regions_df)[1]){
rs_id = regions_df[i, 'rs_id']
pos = regions_df[i, 'pos']
gene_id = regions_df[i, 'gene_id']
region_coords = c(filtered_annotations[which(filtered_annotations$type=='gene' & filtered_annotations$gene_id ==gene_id),'start'], filtered_annotations[which(filtered_annotations$type=='gene' & filtered_annotations$gene_id ==gene_id),'end'])
chr = regions_df[i,'chr']
RNA_peak_metadata = filtered_annotations[which(filtered_annotations$type=='exon' & filtered_annotations$gene_id==gene_id),c("seqnames", "start", "end", "strand")]
colnames(RNA_peak_metadata)[1]='chr'
genotype=find_genotype(gene_id, region_coords)
RNA_peak_annot = find_peak_annotations(region_coords, chr, RNA_peak_metadata)
RNA_track_data = find_track_data(genotype, chr, RNA_meta_df)
RNA_coverage = plotCoverage(exons = RNA_peak_annot$peak_list, cdss = RNA_peak_annot$peak_list, track_data = RNA_track_data, rescale_introns = TRUE,
transcript_annotations = RNA_peak_annot$peak_annot, fill_palette = getGenotypePalette(),
connect_exons = FALSE, transcript_label = FALSE, plot_fraction = 0.1, heights = c(0.7,0.3),
region_coords = region_coords, return_subplots_list = TRUE, coverage_type = "line")
RNA_coverage_plotlist[[i]] = RNA_coverage$coverage_plot
print(RNA_coverage$coverage_plot)
ggsave(paste0('/gpfs/hpchome/evelin95/plots/ca_splicing/',gene_id,'.pdf'))
}
Read 454 items
Column `genotype_id` joining factor and character vector, coercing into character vectorRead 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
Read 454 items
































LS0tCnRpdGxlOiAiS3JvbWF0aWluaSBhdmF0dXNlIGphIHNwbGFpc3NpbWlzZSBzZW9zdGUgdmlzdWFsaXNlZXJpbWluZSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CnBhdGggPSAiL2dwZnMvaHBjaG9tZS9hNzIwOTQvcm9ja2V0L3Byb2plY3RzL2Nocm9tYXRpbl90b19zcGxpY2luZy8iCmxpYnJhcnkoImRwbHlyIikKbGlicmFyeSgicmVhZHIiKQpsaWJyYXJ5KCJkZXZ0b29scyIpCmxpYnJhcnkoInJ0cmFja2xheWVyIikKbGlicmFyeSgid2lnZ2xlcGxvdHIiKQpsaWJyYXJ5KCJHZW5vbWljUmFuZ2VzIikKbGlicmFyeSgnUnNhbXRvb2xzJykKbGlicmFyeSgndGlkeXInKQpsb2FkX2FsbCgiL2dwZnMvcm9ja2V0L2hvbWUvYTcyMDk0L3Byb2plY3RzL2Nocm9tYXRpbl90b19zcGxpY2luZy9zZXFVdGlscy8iKQpgYGAKCgpTcGxhaXNzaW1pc2UgYW5kbWVkCmBgYHtyfQojZ2VlbmlkLCBtaWxsZWwgbGVpZHViIHNwbGFpc3MgUVRMCnNwbGljaW5nID0gcmVhZC50YWJsZShwYXN0ZTAocGF0aCwgInRhYml4L3R4cmV2aXNlLnNpZ25pZmljYW50LmNvbnRhaW5lZC5zb3J0ZWQudHh0Lmd6IikpCgojcjIgc2VvdHVkIHNwbGFzcyBqYSBjYSBsb29rdXN0ZSBwYWFyaWQKY2Ffc3BsaWNpbmcgPSByZWFkLnRhYmxlKHBhc3RlMChwYXRoLCAicmVzdWx0cy9yc3F1YXJlZDA4L2Nxbl9jb250YWluZWRfcnNxLnR4dCIpKQpgYGAKCktyb21hdGlpbmkgYXZhdHVzZSBhbmRtZWQKCkFsdXNla3MgcGVhdmFkIG9sZW1hIGtyb21hdGlpbmkgYXZhdHVzZSBrw7xobXVkLCBtaWxsZWwgbGVpZHViOgoxLiBzdGF0aXN0aWxpc2VsdCBvbHVsaW5lIGNhUVRMIDI1ODcyCjIuIGNhUVRMIG9uIHNlb3R1ZCBzcGxhaXNzIFFUTCdnYSAKCgpBbHVzdHVzZWtzIGxlaWFuIGvDtWlrIGvDvGhtdWQsIG1pcyB2YXN0YXZhZCBrcml0ZWVyaXVtaXRlbGUKYGBge3J9CmNhX2ludGVyZXN0aW5nX3BlYWtzID0gY2Fbd2hpY2goY2EkVjggJWluJSBjYV9zcGxpY2luZyRWMSksXQppbnRlcmVzdGluZ19wZWFrcyA9IGRwbHlyOjpzZWxlY3QoY2FfaW50ZXJlc3RpbmdfcGVha3MsIGMoIlYxIiwgIlYyIiwgIlYzIiwgIlY0IiwgIlY4IiwgIlY5IiwgIlYxMCIsICJWMTciLCJWMTkiKSkKY29sbmFtZXMoaW50ZXJlc3RpbmdfcGVha3MpID0gYygicGVha19pZCIsInBlYWtfY2hyIiwgInBlYWtfc3RhcnQiLCAicGVha19lbmQiLCAicGVha19zbnBpZCIsICJwZWFrX3NucF9jaHIiLCAicGVha19zbnBfcG9zIiwgInBlYWtfc2xvcGUiLCAiY2FfcHZhbHVlIikKaW50ZXJlc3RpbmdfcGVha3MKYGBgCgoKR2VlbmlkLCBtaWxsZSBzcGxhaXNzaW1pbmUgb24gUjIgc2VvdHVkIGtyb21hdGlpbmkgYXZhdHVzZWdhCmBgYHtyfQppbnRlcmVzdGluZ19nZW5lcyA9IHNwbGljaW5nW3doaWNoKHNwbGljaW5nJFYxMCAlaW4lIGNhX3NwbGljaW5nJFY0KSxjKCJWMSIsICJWMiIsICJWMyIsIlY0IiwiVjEwIiwiVjEyIiwiVjE5IiwiVjIxIildCmNvbG5hbWVzKGludGVyZXN0aW5nX2dlbmVzKSA9IGMoImdlbmVfaWQiLCAiZ2VuZV9jaHIiLCJnZW5lX3N0YXJ0IiwiZ2VuZV9lbmQiLCJnZW5lX3NucGlkIiwgImdlbmVfc25wX3BvcyIsImdlbmVfc2xvcGUiLCJnZW5lX3B2YWx1ZSIpCmludGVyZXN0aW5nX2dlbmVzCmBgYAoKYGBge3J9CmhlYWQoY2Ffc3BsaWNpbmcpCmBgYAoKCgpTZW9uIGtyb21hdGlpbmkga8O8aG11ZCBqYSBnZWVuaWQKYGBge3J9CmludGVyZXN0aW5nID0gZHBseXI6OmxlZnRfam9pbihpbnRlcmVzdGluZ19nZW5lcywgY2Ffc3BsaWNpbmcsIGJ5ID0gYygiZ2VuZV9zbnBpZCI9IlY0IikpWzE6OV0gJT4lIGxlZnRfam9pbihpbnRlcmVzdGluZ19wZWFrcywgLiwgYnk9YygncGVha19zbnBpZCc9J1YxJykpCmludGVyZXN0aW5nID0gZHBseXI6OnNlbGVjdChpbnRlcmVzdGluZywgLW9uZV9vZignY3RjZl9jaHInLCdnZW5lX2NocicsICdwZWFrX3NucF9jaHInKSkKaW50ZXJlc3RpbmckZ2VuZV9pZCA9IHN1YnN0cihpbnRlcmVzdGluZyRnZW5lX2lkLCAxLCBuY2hhcigiRU5TRzAwMDAwMTcxNzM1LmNvbnRhaW5lZCIpLTEwKQppbnRlcmVzdGluZwpgYGAKCmBgYHtyfQp3cml0ZS50YWJsZShpbnRlcmVzdGluZywgZmlsZSA9IHBhc3RlMChwYXRoLCAnaW50ZXJlc3RpbmcudHh0JyksIGNvbC5uYW1lcyA9IFQsIHF1b3RlID0gRiwgcm93Lm5hbWVzID0gRiwgYXBwZW5kID0gRikKYGBgCgpgYGB7cn0KaW50ZXJlc3RpbmcgPSByZWFkLnRhYmxlKHBhc3RlMChwYXRoLCAnaW50ZXJlc3RpbmcudHh0JyksIGhlYWRlciA9IFRSVUUpCmBgYAoKYGBge3J9CmZpbHRlcmVkID0gaW50ZXJlc3Rpbmdbd2hpY2goYWJzKGludGVyZXN0aW5nJHBlYWtfc2xvcGUpPjAuNCAmIGFicyhpbnRlcmVzdGluZyRnZW5lX3Nsb3BlKT4wLjQgJiBpbnRlcmVzdGluZyRjYV9wdmFsdWU8MWUtNCAmIGludGVyZXN0aW5nJGdlbmVfcHZhbHVlPDFlLTQpLF0KZmlsdGVyZWQKYGBgCgoKIyBBVEFDCmBgYHtyfQojcHJvb3ZpZApBVEFDX3NhbXBsZV9tZXRhZGF0YSA9IHJlYWQudGFibGUocGFzdGUwKHBhdGgsJ1FDX21lYXN1cmVzL3J1bl9zYW1wbGVfYWNjZXNzaW9uX1BoYXNlSUlJLnR4dCcpKQpjb2xuYW1lcyhBVEFDX3NhbXBsZV9tZXRhZGF0YSkgPSBjKCJzYW1wbGVfaWQiLCAiZ2Vub3R5cGVfaWQiKQpBVEFDX3NhbXBsZV9tZXRhZGF0YVsiY29uZGl0aW9uX25hbWUiXSA9IHJlcCgibmFpdmUiLCBkaW0oQVRBQ19zYW1wbGVfbWV0YWRhdGEpWzFdKQpgYGAKCmBgYHtyfQojZ2Vub3TDvMO8YmlkCnZjZl9maWxlID0gcmVhZFJEUyhwYXN0ZTAocGF0aCwgJ2dlbm90eXBlcy9LdW1hc2FrYV8xMDBfc2FtcGxlcy5tZXJnZWQucmRzJykpCmBgYAoKYGBge3J9CkFUQUNfbWV0YV9kZiA9IHJlYWQudGFibGUocGFzdGUwKHBhdGgsICdBVEFDX21ldGFfZGYnKSwgaGVhZGVyID0gVFJVRSkKQVRBQ19wZWFrX21ldGFkYXRhID0gcmVhZC50YWJsZShwYXN0ZTAocGF0aCwnQVRBQ19wZWFrX21ldGFkYXRhJyksIGhlYWRlciA9IFRSVUUpCmBgYAoKCmBgYHtyfQpyZWdpb25zX2RmID0gdW5pcXVlKGZpbHRlcmVkWyxjKCdwZWFrX2lkJywgJ3BlYWtfY2hyJywncGVha19zdGFydCcsICdwZWFrX2VuZCcsJ3BlYWtfc25waWQnLCdnZW5lX2lkJywgJ3BlYWtfY2hyJywnZ2VuZV9zdGFydCcsICdnZW5lX2VuZCcsJ2dlbmVfc25waWQnLCdnZW5lX3NucF9wb3MnKV0pCmNvbG5hbWVzKHJlZ2lvbnNfZGYpID0gYygncGVha19pZCcsICdwZWFrX2NocicsICdwZWFrX3N0YXJ0JywgJ3BlYWtfZW5kJywgJ3BlYWtfcnNfaWQnLCAnZ2VuZV9pZCcsICdnZW5lX2NocicsICdnZW5lX3N0YXJ0JywgJ2dlbmVfZW5kJywgJ2dlbmVfcnNfaWQnLCAnZ2VuZV9wb3MnKQpyZWdpb25zX2RmCmBgYAoKCmBgYHtyfQojcm0odmNmX2ZpbGUsQVRBQ19jb3VudHMpCmBgYAoKIyBSTkEKYGBge3J9ClJOQV9zYW1wbGVfbWV0YWRhdGEgPSByZWFkLnRhYmxlKCIvZ3Bmcy9ocGNob21lL2E3MjA5NC9ocGMvZGF0YXNldHMvY29udHJvbGxlZF9hY2Nlc3MvU2FtcGxlQXJjaGVvbG9neS9zdHVkaWVzL2NsZWFuZWQvR0VVVkFESVMudHN2IiwgaGVhZGVyID0gVFJVRSlbLGMoInNhbXBsZV9pZCIsImdlbm90eXBlX2lkIiwiY29uZGl0aW9uIildCmNvbG5hbWVzKFJOQV9zYW1wbGVfbWV0YWRhdGEpWzNdID0gImNvbmRpdGlvbl9uYW1lIgpgYGAKCmBgYHtyfQppZiAoRkFMU0UpewogICMgUk5BIHNlcSBsdWdlbWl0ZSBhcnYgdXNlZCBmb3IgY2FsY3VsYXRpbmcgbGlicmFyeSBzaXplCiAgUk5BX2NvdW50cyA9IHJlYWQudGFibGUoIi9ncGZzL2hwY2hvbWUvYTcyMDk0L2hwYy9wcm9qZWN0cy9STkFzZXFfcGlwZWxpbmUvcmVzdWx0cy9leHByZXNzaW9uX21hdHJpY2VzL2ZlYXR1cmVDb3VudHMvR0VVVkFESVMudHN2Lmd6IiwgaGVhZGVyID0gVFJVRSkKICBSTkFfbWV0YV9kZiA9IHdpZ2dsZXBsb3RyQ29uc3RydWN0TWV0YWRhdGEoUk5BX2NvdW50cywgUk5BX3NhbXBsZV9tZXRhZGF0YSwgIi9ncGZzL2hwYy9ob21lL2E3MjA5NC9wcm9qZWN0cy9STkFzZXFfcGlwZWxpbmUvcHJvY2Vzc2VkL0dFVVZBRElTL2JpZ3dpZyIsIGJpZ1dpZ19zdWZmaXggPSAiLnN0cjEuYnciLCBjb25kaXRpb25fbmFtZV9sZXZlbHMgPSBjKCJuYWl2ZSIpKQogIHJtKFJOQV9jb3VudHMpCiAgc2F2ZVJEUyhSTkFfbWV0YV9kZiwgcGFzdGUwKHBhdGgsICdSTkFfbWV0YV9kZicpKQp9CmBgYAoKYGBge3J9ClJOQV9tZXRhX2RmID0gcmVhZFJEUyhwYXN0ZTAocGF0aCwgJ1JOQV9tZXRhX2RmJykpClJOQV9tZXRhX2RmCmBgYAoKCmBgYHtyfQpyZWdpb25zX2RmID0gdW5pcXVlKGZpbHRlcmVkWyxjKCdnZW5lX2lkJywgJ3BlYWtfY2hyJywnZ2VuZV9zdGFydCcsICdnZW5lX2VuZCcsJ2dlbmVfc25waWQnLCdnZW5lX3NucF9wb3MnKV0pCmNvbG5hbWVzKHJlZ2lvbnNfZGYpID0gYygnZ2VuZV9pZCcsICdjaHInLCAnc3RhcnQnLCAnZW5kJywgJ3JzX2lkJywgJ3BvcycpCnJlZ2lvbnNfZGYKYGBgCgpnZWVuaWRlIGFubm90YXRzaW9vbmlkIGphIHRyYW5za3JpcHRpZGUgYW5ub3RhdHNpb29uaWQKYGBge3J9CmlmIChGQUxTRSl7CiAgZ3RmX2RmIDwtIGFzLmRhdGEuZnJhbWUocnRyYWNrbGF5ZXI6OmltcG9ydChwYXN0ZTAocGF0aCwgJ2dlbm90eXBlcy9Ib21vX3NhcGllbnMuR1JDaDM4Ljk2LmNoci5ndGYuZ3onKSkpCiAgZmlsdGVyZWRfYW5ub3RhdGlvbnMgPSBndGZfZGZbZ3RmX2RmJGdlbmVfaWQgJWluJSByZWdpb25zX2RmJGdlbmVfaWQsXQogIGZpbHRlcmVkX2Fubm90YXRpb25zCiAgcm0oZ3RmX2RmKQogIHNhdmVSRFMoZmlsdGVyZWRfYW5ub3RhdGlvbnMsIHBhc3RlMChwYXRoLCAnZmlsdGVyZWRfYW5ub3RhdGlvbnMnKSkKfQpgYGAKCgpgYGB7cn0KZmlsdGVyZWRfYW5ub3RhdGlvbnMgPSByZWFkUkRTKHBhc3RlMChwYXRoLCAnZmlsdGVyZWRfYW5ub3RhdGlvbnMnKSkKZmlsdGVyZWRfYW5ub3RhdGlvbnMKYGBgCgoKS29payBnZWVuaSBla3NvbmlkIEdSYW5nZXMgb2JqZWt0aWRlbmEKYGBge3J9CmZpbmRfcGVha19hbm5vdGF0aW9ucyA9IGZ1bmN0aW9uKHJlZ2lvbl9jb29yZHMsIGNociwgUk5BX3BlYWtfbWV0YWRhdGEpewogIFJOQV9wZWFrX2Fubm90ID0gd2lnZ2xlcGxvdHJFeHRyYWN0UGVha3MocmVnaW9uX2Nvb3JkcywgY2hyb20gPSBjaHIsIFJOQV9wZWFrX21ldGFkYXRhKQogIFJOQV9wZWFrX2Fubm90JHBlYWtfYW5ub3QkdHJhbnNjcmlwdF9pZD0nUk5BJwogIFJOQV9wZWFrX2Fubm90JHBlYWtfYW5ub3QkZ2VuZV9pZCA9ICdSTkEnCiAgUk5BX3BlYWtfYW5ub3QkcGVha19hbm5vdCRnZW5lX25hbWUgPSAnUk5BLXNlcScKICBuYW1lcyhSTkFfcGVha19hbm5vdCRwZWFrX2xpc3QpID0gJ1JOQScKICByZXR1cm4oUk5BX3BlYWtfYW5ub3QpCn0KYGBgCgpMZWlhbiB2Y2YgZmFpbGlzdCBsb2lndSwgbWlzIHZhc3RhYiB1dXJpdGF2YWxlIGdlZW5pbGUKYGBge3J9CmZpbmRfZ2Vub3R5cGUgPSBmdW5jdGlvbihnZW5lX2lkLCByZWdpb25fY29vcmRzKXsKICBsaWJyYXJ5KEdlbm9taWNSYW5nZXMpCiAgZ2VuZV9yYW5nZSA9IEdSYW5nZXMoc2VxbmFtZXMgPWZpbHRlcmVkX2Fubm90YXRpb25zW3doaWNoKGZpbHRlcmVkX2Fubm90YXRpb25zJHR5cGU9PSdnZW5lJyAmIGZpbHRlcmVkX2Fubm90YXRpb25zJGdlbmVfaWQgPT1nZW5lX2lkKSwnc2VxbmFtZXMnXSwgc3RyYW5kID0gYygiKiIpLCByYW5nZXMgPSBJUmFuZ2VzKHN0YXJ0ID0gcmVnaW9uX2Nvb3Jkc1sxXSwgZW5kID0gcmVnaW9uX2Nvb3Jkc1syXSwgbmFtZXMgPSBnZW5lX2lkKSkKICB2Y2ZfZmlsZSA9IHBhc3RlMChwYXRoLCAnZ2Vub3R5cGVzL0dFVVZBRElTX0dSQ2gzOF9maWx0ZXJlZC52Y2YuZ3onKQogIGdlbm90eXBlID0gc2NhblRhYml4RGF0YUZyYW1lKHZjZl9maWxlLCBnZW5lX3JhbmdlLCBjb2xfbmFtZXMgPSBGQUxTRSlbWzFdXQogICNzYXZlUkRTKGdlbm90eXBlLCBwYXN0ZTAocGF0aCwgJ2dlbm90eXBlJykpCiAgCiAgI3pncmVwIC1tIDEgIiNDSFJPTSIgR0VVVkFESVNfR1JDaDM4X2ZpbHRlcmVkLnZjZi5neiA+IHZjZl9nZW5vdHlwZV9pZAogICN2aW0gdmNmX2dlbm90eXBlX2lkIGRlbGV0ZSAjCiAgCiAgdiA9IHNjYW4ocGFzdGUwKHBhdGgsICcvZ2Vub3R5cGVzL3ZjZl9nZW5vdHlwZV9pZCcpLCBjaGFyYWN0ZXIoKSwgcXVvdGUgPSAiIikKICAjdW5saW5rKHBhc3RlMChwYXRoLCAnL2dlbm90eXBlcy92Y2ZfZ2Vub3R5cGVfaWQnKSkKICBjb2xuYW1lcyhnZW5vdHlwZSkgPSB2CiAgCiAgZ2Vub3R5cGVbZ2Vub3R5cGU9PSIwfDAiXTwtMAogIGdlbm90eXBlW2dlbm90eXBlPT0iMXwwIl08LTEKICBnZW5vdHlwZVtnZW5vdHlwZT09IjB8MSJdPC0xCiAgZ2Vub3R5cGVbZ2Vub3R5cGU9PSIxfDEiXTwtMgogIAogIHJldHVybihnZW5vdHlwZSkKfQpgYGAKCgpgYGB7cn0KZmluZF90cmFja19kYXRhID0gZnVuY3Rpb24oZ2Vub3R5cGUsIGNociwgUk5BX21ldGFfZGYpewogICMgYWRkIGNvbG91ciBncm91cAogIGNvbG91cl9ncm91cCA9IGdlbm90eXBlW3doaWNoKGdlbm90eXBlJENIUk9NPT1jaHIgJiBnZW5vdHlwZSRQT1M9PXBvcyksIF0gJT4lIHNlbGVjdCgxMDo0NTQpICU+JSBnYXRoZXIoLiwga2V5PSBjb2xuYW1lcyguKSwgdmFsdWU9LlsxLF0pCiAgY29sbmFtZXMoY29sb3VyX2dyb3VwKSA9IGMoJ2dlbm90eXBlX2lkJywgJ2NvbG91cl9ncm91cCcpCiAgCiAgUk5BX3RyYWNrX2RhdGEgPSBkcGx5cjo6bGVmdF9qb2luKFJOQV9tZXRhX2RmLCBjb2xvdXJfZ3JvdXAsIGJ5PSdnZW5vdHlwZV9pZCcpICU+JSBkcGx5cjo6bXV0YXRlKHRyYWNrX2lkID0gIlJOQS1zZXEiKQogIFJOQV90cmFja19kYXRhWywgJ2NvbG91cl9ncm91cCddID0gYXMuZmFjdG9yKFJOQV90cmFja19kYXRhWywgJ2NvbG91cl9ncm91cCddKQogIHJldHVybihSTkFfdHJhY2tfZGF0YSkKfQpgYGAKCgpBVEFDIGpvb25pc2VkCmBgYHtyfQpqb2ludF9wbG90bGlzdCA9IGxpc3QoKQoKZm9yIChpIGluIDE6ZGltKHJlZ2lvbnNfZGYpWzFdKXsKICBBVEFDX3JzX2lkID0gcmVnaW9uc19kZltpLCAncGVha19yc19pZCddCiAgQVRBQ19yZWdpb25fY29vcmRzPWMocmVnaW9uc19kZltpLCdwZWFrX3N0YXJ0J10tMTAwMCwgcmVnaW9uc19kZltpLCdwZWFrX2VuZCddKzEwMDApCiAgY2hyID0gcmVnaW9uc19kZltpLCdwZWFrX2NociddCiAgQVRBQ19wZWFrX2Fubm90ID0gd2lnZ2xlcGxvdHJFeHRyYWN0UGVha3MocmVnaW9uX2Nvb3JkcywgY2hyb20gPSBjaHIsIEFUQUNfcGVha19tZXRhZGF0YSkKICAKICAjIGFkZCBjb2xvdXIgZ3JvdXAKICBBVEFDX2NvbG91cl9ncm91cCA9IGRhdGEuZnJhbWUoZ2Vub3R5cGVfaWQgPSBuYW1lcyh2Y2ZfZmlsZSRnZW5vdHlwZXNbQVRBQ19yc19pZCxdKSwgY29sb3VyX2dyb3VwPXZjZl9maWxlJGdlbm90eXBlc1tyc19pZCxdKQogIEFUQUNfdHJhY2tfZGF0YSA9IGRwbHlyOjpsZWZ0X2pvaW4oQVRBQ19tZXRhX2RmLCBBVEFDX2NvbG91cl9ncm91cCwgYnk9J2dlbm90eXBlX2lkJykgJT4lIGRwbHlyOjptdXRhdGUodHJhY2tfaWQgPSAiQVRBQy1zZXEiKQogIEFUQUNfdHJhY2tfZGF0YVssICdjb2xvdXJfZ3JvdXAnXSA9IGFzLmZhY3RvcihBVEFDX3RyYWNrX2RhdGFbLCAnY29sb3VyX2dyb3VwJ10pCiAgCiAgQVRBQ19jb3ZlcmFnZSA9IHBsb3RDb3ZlcmFnZShleG9ucyA9IEFUQUNfcGVha19hbm5vdCRwZWFrX2xpc3QsIGNkc3MgPSBBVEFDX3BlYWtfYW5ub3QkcGVha19saXN0LCB0cmFja19kYXRhID0gQVRBQ190cmFja19kYXRhLCByZXNjYWxlX2ludHJvbnMgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNjcmlwdF9hbm5vdGF0aW9ucyA9IEFUQUNfcGVha19hbm5vdCRwZWFrX2Fubm90LCBmaWxsX3BhbGV0dGUgPSBnZXRHZW5vdHlwZVBhbGV0dGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0X2V4b25zID0gRkFMU0UsIHRyYW5zY3JpcHRfbGFiZWwgPSBGQUxTRSwgcGxvdF9mcmFjdGlvbiA9IDAuMSwgaGVpZ2h0cyA9IGMoMC43LDAuMyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbl9jb29yZHMgPSBBVEFDX3JlZ2lvbl9jb29yZHMsIHJldHVybl9zdWJwbG90c19saXN0ID0gVFJVRSwgY292ZXJhZ2VfdHlwZSA9ICJsaW5lIikKICAKICAKICBqb2ludF9wbG90ID0gY293cGxvdDo6cGxvdF9ncmlkKEFUQUNfY292ZXJhZ2UkY292ZXJhZ2VfcGxvdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRBQ19jb3ZlcmFnZSR0eF9zdHJ1Y3R1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ24gPSAidiIsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMywyKSkKICAKICBqb2ludF9wbG90bGlzdFtbaV1dID0gam9pbnRfcGxvdAogIHByaW50KGpvaW50X3Bsb3QpCiAgZ2dzYXZlKHBhc3RlMCgnL2dwZnMvaHBjaG9tZS9ldmVsaW45NS9wbG90cy9jYV9zcGxpY2luZy8nLHJlZ2lvbnNfZGZbaSwncGVha19pZCddLCcucGRmJykpCiAgCn0KYGBgCgpSTkEgam9vbmlzZWQKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKUk5BX2pvaW50X3Bsb3RsaXN0ID0gbGlzdCgpCmZvciAoaSBpbiAxOmRpbShyZWdpb25zX2RmKVsxXSl7CiAgZ2VuZV9yc19pZCA9IHJlZ2lvbnNfZGZbaSwgJ2dlbmVfcnNfaWQnXQogIHBvcyA9IHJlZ2lvbnNfZGZbaSwgJ2dlbmVfcG9zJ10KICBnZW5lX2lkID0gcmVnaW9uc19kZltpLCAnZ2VuZV9pZCddCiAgZ2VuZV9yZWdpb25fY29vcmRzID0gYyhmaWx0ZXJlZF9hbm5vdGF0aW9uc1t3aGljaChmaWx0ZXJlZF9hbm5vdGF0aW9ucyR0eXBlPT0nZ2VuZScgJiBmaWx0ZXJlZF9hbm5vdGF0aW9ucyRnZW5lX2lkID09Z2VuZV9pZCksJ3N0YXJ0J10sIGZpbHRlcmVkX2Fubm90YXRpb25zW3doaWNoKGZpbHRlcmVkX2Fubm90YXRpb25zJHR5cGU9PSdnZW5lJyAmIGZpbHRlcmVkX2Fubm90YXRpb25zJGdlbmVfaWQgPT1nZW5lX2lkKSwnZ2VuZV9lbmQnXSkKICBjaHIgPSByZWdpb25zX2RmW2ksJ2dlbmVfY2hyJ10KICAKICBSTkFfcGVha19tZXRhZGF0YSA9IGZpbHRlcmVkX2Fubm90YXRpb25zW3doaWNoKGZpbHRlcmVkX2Fubm90YXRpb25zJHR5cGU9PSdleG9uJyAmIGZpbHRlcmVkX2Fubm90YXRpb25zJGdlbmVfaWQ9PWdlbmVfaWQpLGMoInNlcW5hbWVzIiwgInN0YXJ0IiwgImVuZCIsICJzdHJhbmQiKV0KICBjb2xuYW1lcyhSTkFfcGVha19tZXRhZGF0YSlbMV09J2NocicKICAKICBnZW5vdHlwZT1maW5kX2dlbm90eXBlKGdlbmVfaWQsIGdlbmVfcmVnaW9uX2Nvb3JkcykKICAKICBSTkFfcGVha19hbm5vdCA9IGZpbmRfcGVha19hbm5vdGF0aW9ucyhnZW5lX3JlZ2lvbl9jb29yZHMsIGNociwgUk5BX3BlYWtfbWV0YWRhdGEpCiAgUk5BX3RyYWNrX2RhdGEgPSBmaW5kX3RyYWNrX2RhdGEoZ2Vub3R5cGUsIGNociwgUk5BX21ldGFfZGYpCiAgCiAgaWYgKHN1bShpcy5uYShSTkFfdHJhY2tfZGF0YSRjb2xvdXJfZ3JvdXApKTwxMDApewogIFJOQV9jb3ZlcmFnZSA9IHBsb3RDb3ZlcmFnZShleG9ucyA9IFJOQV9wZWFrX2Fubm90JHBlYWtfbGlzdCwgY2RzcyA9IFJOQV9wZWFrX2Fubm90JHBlYWtfbGlzdCwgdHJhY2tfZGF0YSA9IFJOQV90cmFja19kYXRhLCByZXNjYWxlX2ludHJvbnMgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2NyaXB0X2Fubm90YXRpb25zID0gUk5BX3BlYWtfYW5ub3QkcGVha19hbm5vdCwgZmlsbF9wYWxldHRlID0gZ2V0R2Vub3R5cGVQYWxldHRlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdF9leG9ucyA9IEZBTFNFLCB0cmFuc2NyaXB0X2xhYmVsID0gRkFMU0UsIHBsb3RfZnJhY3Rpb24gPSAwLjEsIGhlaWdodHMgPSBjKDAuNywwLjMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpb25fY29vcmRzID0gcmVnaW9uX2Nvb3JkcywgcmV0dXJuX3N1YnBsb3RzX2xpc3QgPSBUUlVFLCBjb3ZlcmFnZV90eXBlID0gImxpbmUiKQogIAogIAogIGpvaW50X3Bsb3QgPSBjb3dwbG90OjpwbG90X2dyaWQoUk5BX2NvdmVyYWdlJGNvdmVyYWdlX3Bsb3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJOQV9jb3ZlcmFnZSR0eF9zdHJ1Y3R1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ24gPSAidiIsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMywyKSkKCiAgUk5BX2pvaW50X3Bsb3RsaXN0W1tpXV0gPSBqb2ludF9wbG90CiAgcHJpbnQoam9pbnRfcGxvdCkKICBnZ3NhdmUocGFzdGUwKCcvZ3Bmcy9ocGNob21lL2V2ZWxpbjk1L3Bsb3RzL2NhX3NwbGljaW5nLycsZ2VuZV9pZCwnLnBkZicpKSAgCiAgfQp9CmBgYAoKCgo=